import time
import psutil
import json
import os
from datetime import datetime
import threading

class PerformanceMonitor:
    """性能监控工具，监控CPU、内存、GPU使用情况"""
    
    def __init__(self, log_dir: str = "../../数据管理/game_logs/performance"):
        self.log_dir = log_dir
        os.makedirs(self.log_dir, exist_ok=True)
        self.running = False
        self.thread = None
        self.interval = 5  # 监控间隔（秒）
    
    def start_monitoring(self, interval: int = 5):
        """开始监控"""
        self.interval = interval
        self.running = True
        self.thread = threading.Thread(target=self._monitor_loop, daemon=True)
        self.thread.start()
        print(f"性能监控已启动，间隔 {interval} 秒")
    
    def stop_monitoring(self):
        """停止监控"""
        self.running = False
        if self.thread:
            self.thread.join()
        print("性能监控已停止")
    
    def _monitor_loop(self):
        """监控循环"""
        while self.running:
            metrics = self.get_current_metrics()
            self.log_metrics(metrics)
            time.sleep(self.interval)
    
    def get_current_metrics(self):
        """获取当前性能指标"""
        # CPU使用率
        cpu_usage = psutil.cpu_percent(interval=1)
        
        # 内存使用率
        mem = psutil.virtual_memory()
        mem_usage = mem.percent
        
        # GPU使用率（需要nvidia-smi支持）
        gpu_usage = self._get_gpu_usage()
        
        return {
            "timestamp": datetime.now().isoformat(),
            "cpu_usage_percent": cpu_usage,
            "memory_usage_percent": mem_usage,
            "gpu_usage_percent": gpu_usage,
            "process_count": len(psutil.pids())
        }
    
    def _get_gpu_usage(self):
        """获取GPU使用率（NVIDIA）"""
        try:
            import pynvml
            pynvml.nvmlInit()
            handle = pynvml.nvmlDeviceGetHandleByIndex(0)
            util = pynvml.nvmlDeviceGetUtilizationRates(handle)
            pynvml.nvmlShutdown()
            return util.gpu
        except Exception:
            # 若无法获取GPU信息，返回-1
            return -1
    
    def log_metrics(self, metrics: dict):
        """记录性能指标到日志文件"""
        date_str = datetime.now().strftime("%Y%m%d")
        log_file = f"{self.log_dir}/performance_{date_str}.jsonl"
        
        with open(log_file, "a", encoding="utf-8") as f:
            f.write(json.dumps(metrics) + "\n")
    
    def get_recent_metrics(self, minutes: int = 5) -> list:
        """获取最近几分钟的性能指标"""
        date_str = datetime.now().strftime("%Y%m%d")
        log_file = f"{self.log_dir}/performance_{date_str}.jsonl"
        
        if not os.path.exists(log_file):
            return []
        
        recent_metrics = []
        cutoff_time = datetime.now().timestamp() - (minutes * 60)
        
        with open(log_file, "r", encoding="utf-8") as f:
            for line in reversed(list(f)):
                try:
                    metric = json.loads(line)
                    metric_time = datetime.fromisoformat(metric["timestamp"]).timestamp()
                    if metric_time >= cutoff_time:
                        recent_metrics.append(metric)
                    else:
                        break
                except json.JSONDecodeError:
                    continue
        
        return list(reversed(recent_metrics))